import datetime
from typing import Union
from fastapi import FastAPI, Header, Request
from pydantic import BaseModel

from http_helper import HttpHelper
from db_helper import DbHelper
import uvicorn

http = HttpHelper()
db = DbHelper()
app = FastAPI()


class Item(BaseModel):
    name: str
    price: float
    is_offer: Union[bool, None] = None


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.put("/api/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "item_id": item_id}


'''
签到
'''


@app.get("/api/check-in")
def check_in(openid: str = Header()):
    if db.check_in(openid):
        return resp_ok({})
    else:
        return resp_error('签到失败', 1003)


@app.get("/api/my-info")
def get_my_info(openid: str = Header()):
    ex = db.find_member_ex(openid)
    if ex is None:
        return resp_error('无用户数据', 1004)

    member = db.find_member(ex.member_id)
    date = datetime.datetime.now().strftime('%Y-%m-%d')
    check_in_data = db.find_check_in(ex.member_id, date)

    return resp_ok({
        "nickname": member.member_name,
        "avatar": member.member_avatar,
        "points": ex.points,
        "checkInStatus": 1 if check_in_data is not None else 0
    })

@app.get("/api/check-in-status")
def check_in_status(openid: str = Header()):
    # all_headers = dict(req.headers)
    # print('status openid:', all_headers)
    return resp_ok({'checkInStatus': db.check_in_status(openid)})


@app.get("/api/bind")
def bind(code: str, phone: str):
    if not db.is_phone_exist(phone):
        return resp_error('手机号未注册', 1000)

    # 调用微信接口
    resp = http.get_openid(code)
    print('openid result:', code, resp)
    if 'errcode' in resp:
        return resp_error('无法获取用户信息', 1002)
    openid = resp['openid']
    if not openid:
        return resp_error('id读取失败', 1001)

    member_ext = db.bind(openid, phone)
    if member_ext is not None:
        # 绑定openid和phone
        return resp_ok(member_ext.to_dict())
    else:
        return resp_error('手机号未注册', 1000)

@app.get('/api/points-history')
def get_points_history(openid: str = Header(default=None)):
    ret = db.get_points_history(openid)
    return resp_ok(ret)

@app.get('/api/ads-data')
def query_ads_data(startTime: str, endTime: str):
    return db.find_top_data(startTime, endTime)

@app.get('/api/act-list')
def query_act_list(region: str):
    return http.fetch_top_activities(100, region)

@app.get('/api/club-finished-act')
def query_finished_act(club_id: int):
    return http.fetch_club_finish_events(club_id, 20)

@app.get('/api/act-detail')
def query_act_detail(act_id: int):
    return http.fetch_activity_detail(act_id)

@app.get('/api/top-members')
def query_top_members():
    return resp_ok(db.find_top_members())

def resp_error(msg, code):
    return {'success': False, 'message': msg, 'code': code}

############################ 20251122比赛专用积分接口 ########################################
@app.get('/api/game-score')
def get_game_score():
    return resp_ok(db.get_game_score())

@app.post('/api/game-score')
async def save_game_score(request: Request):
    gs = await request.json()
    # print('gs:', gs)
    db.save_game_score(gs['team1'], gs['team2'], gs['score1'], gs['score2'])
    return resp_ok(None)

@app.get('/api/pre-score')
def get_pre_score():
    return resp_ok(db.get_pre_score())

@app.post('/api/pre-score')
async def save_pre_score(request: Request):
    gs = await request.json()
    # print('gs:', gs)
    db.save_pre_score(gs['team1'], gs['team2'], gs['score1'], gs['score2'], gs['type'])
    return resp_ok(None)

@app.get('/api/final-score')
def get_final_score():
    return resp_ok(db.get_final_score())

@app.post('/api/final-score')
async def save_final_score(request: Request):
    gs = await request.json()
    # print('gs:', gs)
    db.save_final_score(gs['team1'], gs['team2'], gs['score1'], gs['score2'], gs['type'])
    return resp_ok(None)

def resp_ok(data):
    return {'success': True, 'data': data, 'code': 0}

if __name__ == '__main__':
    uvicorn.run('main:app', host='0.0.0.0', port=8000, reload=True)